package com.tiger.controller;

import com.alibaba.fastjson.JSON;
import com.tiger.utils.UpdateUtils;
import com.tiger.pojo.homePage.HotArticle;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author HuXuehao (StudiousTiger)
 * @desc 这个类的作用是
 * @date 2022/3/11
 */
@Slf4j
@RestController
public class SearchController {
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    private HttpServletRequest httpServletRequest;
    @Autowired
    private UpdateUtils updateUtils;

    /**
     * 获取网站“主页”的搜索到的总页数
     * @param keyWord
     * @return
     */
    @RequestMapping(value = "/search/getAllArticlePages/{classify}/{keyWord}", name = "获取网站“主页”的搜索到的总页数/user")
    public Long getAllArticlePages(@PathVariable String classify,@PathVariable String keyWord){
        try {
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
            boolQueryBuilder.must(QueryBuilders.matchQuery("title",keyWord));
            if (!"hot".equals(classify)) {
                boolQueryBuilder.must(QueryBuilders.matchQuery("classify",classify));
            }

            NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(boolQueryBuilder)
                    .withPageable(PageRequest.of(0, 20))   // 分页
                    .build();
            long totalHits = elasticsearchRestTemplate.search(searchQuery, HotArticle.class).getTotalHits();

            return (double)totalHits/20L > totalHits/20 ? totalHits/20 + 1 : totalHits/20;
        } catch (Exception e) {
            log.error(e.toString());
            return 0L;
        }
    }

    /**
     * 网站“主页”的搜索(分页 + 高亮)
     * @param classify   分类
     * @param keyWord  用户输入的关键字
     * @param currentPage 当前页
     * @return
     */
    @RequestMapping(value = "/search/allArticle/{classify}/{keyWord}/{currentPage}", name = "网站“主页”的搜索(分页 + 高亮)/user")
    public String allArticle(@PathVariable String classify,@PathVariable String keyWord,@PathVariable int currentPage){
        try {
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
            boolQueryBuilder.must(QueryBuilders.matchQuery("title",keyWord));
            if (!"hot".equals(classify)) {
                boolQueryBuilder.must(QueryBuilders.matchQuery("classify",classify));
            }

            NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(boolQueryBuilder)
//                    .withQuery(QueryBuilders.matchQuery("title", queryFiled))
                    .withPageable(PageRequest.of(currentPage - 1, 20))   // 分页
                    .withHighlightFields(new HighlightBuilder.Field("title"))  // 高亮
                    .withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:tomato'>").postTags("</span>"))
                    .build();
            SearchHits<HotArticle> search = elasticsearchRestTemplate.search(searchQuery, HotArticle.class);

            List<org.springframework.data.elasticsearch.core.SearchHit<HotArticle>> searchHits = search.getSearchHits();
            ArrayList<HotArticle> hotArticles = new ArrayList<>();
            for (org.springframework.data.elasticsearch.core.SearchHit<HotArticle> searchHit : searchHits) {
                // 设置高亮字段
                Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
                searchHit.getContent().setTitle(
                        highlightFields.get("title") == null?
                                searchHit.getContent().getTitle()
                                :highlightFields.get("title").get(0)
                );
                hotArticles.add(searchHit.getContent());
            }
            if (hotArticles.size() > 0) {
                for (HotArticle hotArticle : hotArticles) {
                    hotArticle.setUserHeadPhotoPath(
                            updateUtils.getNewHeadPhotoURL(
                                    hotArticle.getUserHeadPhotoPath()
                            )
                    );
                }
                return JSON.toJSONString(hotArticles);
            } else {
                return "empty";
            }

        } catch (Exception e) {
            log.error(e.toString());
            return "false";
        }
    }

    /**
     * 获取个人主页的搜索到的总页数
     * @param classify
     * @param keyWord
     * @param UID
     * @return
     */
    @RequestMapping(value = "/search/getHomePageWorkPages/{classify}/{keyWord}/{UID}", name = " 获取个人主页的搜索到的总页数/user")
    public Long getUserArticlePages(@PathVariable String classify,@PathVariable String keyWord,@PathVariable String UID){
        try {
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
            boolQueryBuilder.must(QueryBuilders.matchQuery("classify",classify));
            boolQueryBuilder.must(QueryBuilders.matchQuery("title",keyWord));
            boolQueryBuilder.must(QueryBuilders.matchQuery("userId",UID));

            NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(boolQueryBuilder)
    //                .withQuery(QueryBuilders.matchQuery("title", queryFiled))
                    .withPageable(PageRequest.of(0, 20))   // 分页
                    .build();
            long totalHits = elasticsearchRestTemplate.search(searchQuery, HotArticle.class).getTotalHits();

            return (double)totalHits/20L > totalHits/20 ? totalHits/20 + 1 : totalHits/20;
        } catch (Exception e) {
            log.error(e.toString());
            return 0L;
        }
    }
    /**
     * 个人主页的搜索
     * @param classify
     * @param keyWord
     * @param UID
     * @param currentPage
     * @return
     */
    @RequestMapping(value = "/search/userWork/{classify}/{keyWord}/{UID}/{currentPage}", name = "个人主页的搜索/user")
    public String userArticle(@PathVariable String classify,@PathVariable String keyWord,@PathVariable String UID,@PathVariable int currentPage){
        try {
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
            boolQueryBuilder.must(QueryBuilders.matchQuery("classify",classify));
            boolQueryBuilder.must(QueryBuilders.matchQuery("title",keyWord));
            boolQueryBuilder.must(QueryBuilders.matchQuery("userId",UID));

            NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(boolQueryBuilder)
//                    .withQuery(QueryBuilders.matchQuery("title", queryFiled))
                    .withPageable(PageRequest.of(currentPage - 1, 20))   // 分页
                    .withHighlightFields(new HighlightBuilder.Field("title"))  // 高亮
                    .withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:tomato'>").postTags("</span>"))
                    .build();
            SearchHits<HotArticle> search = elasticsearchRestTemplate.search(searchQuery, HotArticle.class);

            List<org.springframework.data.elasticsearch.core.SearchHit<HotArticle>> searchHits = search.getSearchHits();
            ArrayList<HotArticle> hotArticles = new ArrayList<>();
            for (org.springframework.data.elasticsearch.core.SearchHit<HotArticle> searchHit : searchHits) {
                // 设置高亮字段
                Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
                searchHit.getContent().setTitle(
                        highlightFields.get("title") == null?
                                searchHit.getContent().getTitle()
                                :highlightFields.get("title").get(0)
                );
                hotArticles.add(searchHit.getContent());
            }
            if (hotArticles.size() > 0) {
                for (HotArticle hotArticle : hotArticles) {
                    hotArticle.setUserHeadPhotoPath(
                            updateUtils.getNewHeadPhotoURL(
                                    hotArticle.getUserHeadPhotoPath()
                            )
                    );
                }
                return JSON.toJSONString(hotArticles);
            } else {
                return "empty";
            }

        } catch (Exception e) {
            log.error(e.toString());
            return "false";
        }
    }

    /**
     * 获取用户管理端 搜索 work 得到的总页数
     * @param classify
     * @param keyWord
     * @return
     */
    @RequestMapping(value = "/search/getUserAdminWorkPages/{classify}/{keyWord}", name = "获取用户管理端 搜索 work 得到的总页数/user")
    public Long getUserAdminWorkPages(@PathVariable String classify,@PathVariable String keyWord){
        try {
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
            boolQueryBuilder.must(QueryBuilders.matchQuery("classify",classify));
            boolQueryBuilder.must(QueryBuilders.matchQuery("title",keyWord));
            boolQueryBuilder.must(QueryBuilders.matchQuery("userId",httpServletRequest.getSession().getAttribute("userId")));

            NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(boolQueryBuilder)
                    //                .withQuery(QueryBuilders.matchQuery("title", queryFiled))
                    .withPageable(PageRequest.of(0, 20))   // 分页
                    .build();
            long totalHits = elasticsearchRestTemplate.search(searchQuery, HotArticle.class).getTotalHits();

            return (double)totalHits/20L > totalHits/20 ? totalHits/20 + 1 : totalHits/20;
        } catch (Exception e) {
            log.error(e.toString());
            return 0L;
        }
    }

    /**
     * 用户管理端 搜索 work
     * @param classify
     * @param keyWord
     * @param currentPage
     * @return
     */
    @RequestMapping(value = "/search/userAdminWork/{classify}/{keyWord}/{currentPage}", name = "用户管理端搜索发布的作品/user")
    public String userAdminWork(@PathVariable String classify,@PathVariable String keyWord,@PathVariable int currentPage){
        try {
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
            boolQueryBuilder.must(QueryBuilders.matchQuery("classify",classify));
            boolQueryBuilder.must(QueryBuilders.matchQuery("title",keyWord));
            boolQueryBuilder.must(QueryBuilders.matchQuery("userId",httpServletRequest.getSession().getAttribute("userId")));

            NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(boolQueryBuilder)
                    .withPageable(PageRequest.of(currentPage - 1, 20))   // 分页
                    .withHighlightFields(new HighlightBuilder.Field("title"))  // 高亮
                    .withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:tomato'>").postTags("</span>"))
                    .build();
            SearchHits<HotArticle> search = elasticsearchRestTemplate.search(searchQuery, HotArticle.class);

            List<org.springframework.data.elasticsearch.core.SearchHit<HotArticle>> searchHits = search.getSearchHits();
            ArrayList<HotArticle> hotArticles = new ArrayList<>();


            for (org.springframework.data.elasticsearch.core.SearchHit<HotArticle> searchHit : searchHits) {
                // 设置高亮字段
                Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
                searchHit.getContent().setTitle(
                        highlightFields.get("title") == null?
                                searchHit.getContent().getTitle()
                                :highlightFields.get("title").get(0)
                );
                hotArticles.add(searchHit.getContent());
            }

            if (hotArticles.size() > 0) {
                for (HotArticle hotArticle : hotArticles) {
                    hotArticle.setUserHeadPhotoPath(
                            updateUtils.getNewHeadPhotoURL(
                                    hotArticle.getUserHeadPhotoPath()
                            )
                    );
                }
                return JSON.toJSONString(hotArticles);
            } else {
                return "empty";
            }

        } catch (Exception e) {
            log.error(e.toString());
            return "false";
        }
    }


    /**
     * 判断索引是否存在
     * @param index
     * @return
     */
    private boolean indexEsExist(String index) {
        boolean indexExist = false;
        try {
            //设置索引
            GetIndexRequest indexRequest = new GetIndexRequest(index);
            indexRequest.local(false);
            indexRequest.humanReadable(true);
            // 往es查询索引
            indexExist = restHighLevelClient.indices().exists(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("索引不存在！！！");
        }
        return indexExist;
    }


}
